<template>
  <div class="p-2">
    <a-form class="smart-query-form">
      <a-row class="smart-query-form-row">
        <a-form-item label="模型标识" class="smart-query-form-item">
          <a-input style="width: 300px" v-model:value="queryForm.modelKey" placeholder="请输入模型标识" />
        </a-form-item>
        <a-form-item label="模型名称" class="smart-query-form-item">
          <a-input style="width: 300px" v-model:value="queryForm.modelName" placeholder="请输入模型名称" />
        </a-form-item>

        <a-form-item class="smart-query-form-item smart-margin-left10">
          <a-button-group>
            <a-button type="primary" @click="onSearch">
              <template #icon>
                <SearchOutlined />
              </template>
              查询
            </a-button>
            <a-button @click="resetQuery">
              <template #icon>
                <ReloadOutlined />
              </template>
              重置
            </a-button>
          </a-button-group>
        </a-form-item>
      </a-row>
    </a-form>
    <a-card size="small" :bordered="false" :hoverable="true">
      <a-row class="smart-table-btn-block">
        <div class="smart-table-operate-block">
          <a-button @click="handleAdd()" type="primary">
            <template #icon>
              <PlusOutlined />
            </template>
            新建模型
          </a-button>
          <a-button @click="handleExport()" type="primary">
            <template #icon>
              <FileExcelOutlined />
            </template>
            导出模型
          </a-button>
          <a-button @click="handleDelete()" type="primary">
            <template #icon>
              <DeleteOutlined />
            </template>
            删除模型
          </a-button>
          <a-button @click="testProcess" type="primary">
            <template #icon>
              <FileOutlined />
            </template>
            测试流程
          </a-button>
        </div>
      </a-row>

      <a-table
        :scroll="{ x: 1300 }"
        size="small"
        :dataSource="tableData"
        :columns="columns"
        rowKey="enterpriseId"
        :pagination="false"
        :loading="tableLoading"
        bordered
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.dataIndex === 'action'">
            <div class="smart-table-operate">
              <a-button type="link" @click="handleUpdate(record)">修改</a-button>
              <a-button type="link" @click="handleDesigner(record)">设计</a-button>
              <a-button type="link" @click="handleDeploy(record)">部署</a-button>
              <a-button type="link" @click="handleHistory(record)">历史</a-button>

              <a-button type="link" @click="handleDelete(record)">删除</a-button>
            </div>
          </template>
        </template>
      </a-table>

      <div class="smart-query-table-page">
        <a-pagination
          showSizeChanger
          showQuickJumper
          show-less-items
          :pageSizeOptions="PAGE_SIZE_OPTIONS"
          :defaultPageSize="queryForm.pageSize"
          v-model:current="queryForm.pageNum"
          v-model:pageSize="queryForm.pageSize"
          :total="total"
          @change="ajaxQuery"
          @showSizeChange="ajaxQuery"
          :show-total="(total) => `共${total}条`"
        />
      </div>
    </a-card>

    <!--  添加或修改模型信息对话框  -->

    <a-modal :title="dialog.title" :open="dialog.visible" width="500px">
      <a-form ref="modelFormRef" :model="form" :rules="rules" :label-col="{ span: 4 }">
        <a-form-item label="模型标识" name="modelKey">
          <a-input v-model:value="form.modelKey" disabled placeholder="请输入模型标识" />
        </a-form-item>
        <a-form-item label="模型名称" name="modelName">
          <a-input v-model:value="form.modelName" :disabled="form.modelId !== undefined" placeholder="请输入模型名称" />
        </a-form-item>
        {{ form.category }}
        <a-form-item label="流程分类" name="category">
          <a-select v-model:value="form.category" placeholder="请选择" style="width: 100%">
            <a-select-option v-for="item in categoryOptions" :value="item.code"> {{ item.categoryName }} </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="描述" name="description">
          <a-input v-model:value="form.description" type="textarea" placeholder="请输入内容" maxlength="200" show-word-limit />
        </a-form-item>
      </a-form>
      <template #footer>
        <a-button type="primary" @click="submitForm">确 定</a-button>
        <a-button @click="cancel">取 消</a-button>
      </template>
    </a-modal>

    <a-modal class="full-modal" :title="designer.title" :footer="null" v-model:open="designer.visible" width="100%">
      <ProcessDesigner
        :key="`designer-${reloadIndex}`"
        ref="modelDesignerRef"
        v-loading="designerLoading"
        :designer-form="designerForm"
        :bpmn-xml="bpmnXml"
        @save="onSaveDesigner"
      />
    </a-modal>

    <a-modal :title="history.title" v-model:open="history.visible" width="70%">
      <a-table
        :loading="historyLoading"
        :dataSource="historyList"
        :columns="historyColumns"
        :scroll="{ x: 1300 }"
        :pagination="false"
        size="small"
        bordered
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.dataIndex === 'version'">
            <a-tag>v{{ record.version }}</a-tag>
          </template>
          <template v-if="column.dataIndex === 'action'">
            <a-button type="link" @click="handleLatest(record)">设为最新</a-button>
            <a-button type="link" @click="handleDeploy(record)">部署</a-button>
          </template>
        </template>
      </a-table>
      <div class="smart-query-table-page">
        <a-pagination
          v-show="historyList.length > 0"
          :total="historyTotal"
          v-model:current="queryForm.pageNum"
          v-model:pageSize="queryForm.pageSize"
          @change="ajaxQuery"
          show-total
        />
      </div>
    </a-modal>

    <!-- 流程图 -->
    <a-modal :title="processDialog.title" v-model:open="processDialog.visible" width="70%">
      <process-viewer :key="`designer-${reloadIndex}`" :xml="processXml" :style="{ height: '650px' }" />
    </a-modal>
  </div>
</template>

<script setup>
  import { modelApi } from '/@/api/workflow/model';
  import { categoryApi } from '/@/api/workflow/category';
  import ProcessDesigner from '/@/components/ProcessDesigner/index.vue';
  import { message, Modal } from 'ant-design-vue';

  import { h } from 'vue';
  import { log } from 'bpmn-js-token-simulation';
  const { proxy } = getCurrentInstance();

  const tableData = ref([]);
  const tableLoading = ref(false);
  const showSearch = ref(true);
  const ids = ref([]);
  const single = ref(true);
  const multiple = ref(true);
  const total = ref(0);
  const categoryOptions = ref([]);
  const designerLoading = ref(true);
  const bpmnXml = ref('');
  const reloadIndex = ref(0);
  const processXml = ref('');

  const historyList = ref([]);
  const historyLoading = ref(true);
  const historyTotal = ref(0);

  const modelFormRef = ref();
  const queryFormRef = ref();
  const modelDesignerRef = ref();

  const columns = ref([
    {
      title: '模型标识',
      dataIndex: 'modelKey',
    },
    {
      title: '模型名称',
      dataIndex: 'modelName',
    },
    {
      title: '流程分类',
      dataIndex: 'category',
    },
    {
      title: '模型版本',
      dataIndex: 'version',
    },
    {
      title: '描述',
      dataIndex: 'description',
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
    },
    {
      title: '操作',
      dataIndex: 'action',
    },
  ]);

  const historyColumns = ref([
    {
      title: '模型标识',
      dataIndex: 'modelKey',
      width: 200,
    },
    {
      title: '模型名称',
      dataIndex: 'modelName',
      width: 180,
    },
    {
      title: '流程分类',
      dataIndex: 'categoryName',
      width: 100,
      customRender: ({ text }) => categoryFormat(text),
    },
    {
      title: '模型版本',
      dataIndex: 'version',
      width: 100,
      customRender: ({ text }) => text,
    },
    {
      title: '描述',
      dataIndex: 'description',
      width: 200,
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      width: 180,
    },
    {
      title: '操作',
      width: 180,
      dataIndex: 'action',
      fixed: 'right',
    },
  ]);

  const dialog = reactive({
    visible: false,
    title: '',
  });

  const processDialog = reactive({
    visible: false,
    title: '流程图',
  });

  const designer = reactive({
    visible: false,
    title: '',
  });

  const history = reactive({
    visible: false,
    title: '',
  });

  const initFormData = {
    modelId: undefined,
    modelKey: `Process_${new Date().getTime()}`,
    modelName: `业务流程_${new Date().getTime()}`,
    category: '',
    description: '',
    formType: undefined,
    formId: undefined,
    bpmnXml: '',
    newVersion: false,
  };

  const data = reactive({
    form: { ...initFormData },
    queryForm: {
      pageNum: 1,
      pageSize: 10,
      modelKey: '',
      modelName: '',
    },
    rules: {
      modelKey: [{ required: true, message: '岗位名称不能为空', trigger: 'blur' }],
      modelName: [{ required: true, message: '岗位编码不能为空', trigger: 'blur' }],
    },
  });

  const designerForm = reactive({
    modelId: '',
    form: {
      processName: '',
      processKey: '',
    },
  });

  const { queryForm, form, rules } = toRefs(data);

  const router = useRouter();

  /** 查询模型列表 */
  const ajaxQuery = async () => {
    try {
      tableLoading.value = true;
      const { data } = await modelApi.listModel(queryForm.value);
      tableData.value = data.list;
      total.value = data.total;
    } catch (error) {
      message.error('查询失败', error);
    } finally {
      tableLoading.value = false;
    }
  };
  /** 取消按钮 */
  const cancel = () => {
    reset();
    dialog.visible = false;
  };
  /** 表单重置 */
  const reset = () => {
    form.value = { ...initFormData };
    modelFormRef.value.resetFields();
  };
  /** 搜索按钮操作 */
  const onSearch = () => {
    queryForm.value.pageNum = 1;
    ajaxQuery();
  };
  /** 重置按钮操作 */
  const resetQuery = () => {
    Object.assign(queryForm.value, {
      pageNum: 1,
      pageSize: 10,
      modelKey: '',
      modelName: '',
    });
    ajaxQuery();
  };
  /** 多选框选中数据 */
  const handleSelectionChange = (selection) => {
    ids.value = selection.map((item) => item.modelId);
    single.value = selection.length != 1;
    multiple.value = !selection.length;
  };
  /** 新增按钮操作 */
  const handleAdd = () => {
    dialog.visible = true;
    dialog.title = '添加模型';
  };
  /** 修改按钮操作 */
  const handleUpdate = (row) => {
    dialog.visible = true;
    dialog.title = '修改模型';
    nextTick(async () => {
      reset();
      const modelId = row?.modelId || ids.value[0];
      const res = await modelApi.getModel(modelId);
      form.value = res.data;
    });
  };
  /** 删除按钮操作 */
  const handleDelete = async (row) => {
    const modelIds = row?.modelId || ids.value;
    Modal.confirm({
      title: '提示',
      content: `是否确认删除参数编号为"${modelIds}"的数据项？`,
      okText: '确认',
      cancelText: '取消',
      onOk: async () => {
        await modelApi.delModel(modelIds);
        ajaxQuery();
        message.success('删除成功');
      },
    });
  };
  /** 导出按钮操作 */
  const handleExport = () => {
    proxy?.download(
      'workflow/model/export',
      {
        ...queryForm.value,
      },
      `model_${new Date().getTime()}.xlsx`
    );
  };
  /** 查看流程图 */
  const handleProcessView = async (row) => {
    reloadIndex.value++;
    // 发送请求，获取xml
    const { data } = await modelApi.getBpmnXml(row.modelId);
    processXml.value = data;
    processDialog.visible = true;
  };
  const testProcess = () => {
    reloadIndex.value++;

    bpmnXml.value = '';
    designerLoading.value = false;
    designer.title = '流程设计 - ' + 1;
    designer.visible = true;
  };
  /** 设计按钮操作 */
  const handleDesigner = async (row) => {
    reloadIndex.value++;
    designerForm.modelId = row.modelId;
    const res = await modelApi.getBpmnXml(row.modelId);
    console.log(res.data);
    bpmnXml.value = res.data || '';
    designerLoading.value = false;

    designer.title = '流程设计 - ' + 1;
    designer.visible = true;
  };
  const handleDeploy = (row) => {
    tableLoading.value = true;
    nextTick(async () => {
      await modelApi.deployModel(row?.modelId);
      message.success('操作成功');
      tableLoading.value = false;
      ajaxQuery();
    });
  };
  const handleLatest = async (row) => {
    Modal.confirm({
      title: '提示',
      content: '是否将此模型保存为新版本?',
      okText: '确认',
      cancelText: '取消',
      onOk: async () => {
        historyLoading.value = true;
        await modelApi.latestModel({ modelId: row.modelId });
        history.visible = false;
        ajaxQuery();
        message.success('操作成功');
        historyLoading.value = false;
      },
    });
  };
  /** 查询历史列表 */
  const getHistoryList = async () => {
    historyLoading.value = true;
    const { data } = await modelApi.historyModel(queryForm.value);
    historyList.value = data.list;
    historyTotal.value = data.total;
    historyLoading.value = false;
  };
  const handleHistory = (row) => {
    history.visible = true;
    history.title = '模型历史';
    queryForm.value.modelKey = row?.modelKey;
    getHistoryList();
  };
  /** 提交表单操作 */
  const submitForm = async () => {
    try {
      await modelFormRef.value.validate();
      form.value.modelId ? await modelApi.updateModel(form.value) : await modelApi.addModel(form.value);
      message.success('操作成功');
      dialog.visible = false;
      ajaxQuery();
    } catch (error) {
      message.error('表单验证失败');
    }
  };
  /** 查询流程分类列表 */
  const getCategoryList = async () => {
    const res = await categoryApi.listAllCategory();
    categoryOptions.value = res.data;
  };

  const onSaveDesigner = async (str) => {
    bpmnXml.value = str;
    let dataBody = {
      modelId: designerForm.modelId,
      bpmnXml: str,
    };
    Modal.confirm({
      title: '提示',
      content: '是否将此模型保存为新版本?',
      okText: '确认',
      cancelText: '取消',
      onOk: () => {
        confirmSave(dataBody, true);
      },
    });
  };
  const confirmSave = async (body, newVersion) => {
    designerLoading.value = true;
    await modelApi.saveModel(Object.assign(body, { newVersion: newVersion }));
    ajaxQuery();
    message.success('保存成功');
    designerLoading.value = false;
    designer.visible = false;
  };

  const categoryFormat = (category) => {
    return categoryOptions.value.find((k) => k.code === category)?.categoryName ?? '';
  };

  const isMounted = ref(false);
  onMounted(() => {
    isMounted.value = true;

    getCategoryList();
    ajaxQuery();
  });
  onActivated(() => {
    if (isMounted.value) {
      ajaxQuery();
    }
  });
</script>

<style scoped>
  .el-dialog__body {
    max-height: calc(100vh) !important;
    overflow-y: auto;
    overflow-x: hidden;
  }
</style>
